package com.effectiv.gooruda.rest.service.api;

import java.util.List;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;

import lombok.Getter;
import lombok.Setter;

import com.effectiv.gooruda.rest.docs.annotation.Api;
import com.effectiv.gooruda.rest.docs.annotation.ApiBodyObject;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeader;
import com.effectiv.gooruda.rest.docs.annotation.ApiHeaders;
import com.effectiv.gooruda.rest.docs.annotation.ApiMethod;
import com.effectiv.gooruda.rest.docs.annotation.ApiParam;
import com.effectiv.gooruda.rest.docs.annotation.ApiResponseObject;
import com.effectiv.gooruda.rest.docs.pojo.ApiVerb;
import com.effectiv.gooruda.rest.domain.Role;
import com.effectiv.gooruda.rest.ext.ExtResponse;
import com.effectiv.gooruda.rest.ext.SecurityContextHolder;

@Path("/role")
@Api(name = "Role API", description = "Role management API.")
public abstract class RoleService {
	
	private final String COLLECTION_BASE = "c_app_role_";
	
	@Getter @Setter
	@Autowired
	private MongoTemplate template;

	protected String getCollection(){
		return COLLECTION_BASE + SecurityContextHolder.get().getId();
	}
	
	protected void throwException(int errorCode, String errorMessage){
		ExtResponse extRes = new ExtResponse();
		extRes.setErrorCode(errorCode);
		extRes.setMessage(errorMessage);
		
		ResponseBuilder resBuilder = Response.status(Status.BAD_REQUEST);
		resBuilder.entity(extRes);
		
		throw new WebApplicationException(resBuilder.build());
	}
	
	/**
	 * Save a role
	 * @param role
	 * @return
	 */
	
	@ApiMethod(path = "/api/role", verb = ApiVerb.POST, description = "Save role details.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	@POST	
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response save(@ApiBodyObject Role role);
	
	/**
	 * Find a role by given name.
	 * @param roleName
	 * @return
	 */
	
	@ApiMethod(path = "/api/role/findbyname/{roleName}", verb = ApiVerb.POST, description = "Find a role by given name.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	
	@Path("/findbyname/{roleName}")
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response findByName(
			@PathParam("roleName") @ApiParam(name="roleName", description="Role name") String roleName);
	
	/**
	 * Find a role by id
	 * @param id
	 * @return
	 */
	@ApiMethod(path = "/api/role/findone/{id}", verb = ApiVerb.POST, description = "Find a role by id.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	
	@Path("/findone/{id}")
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response findOne(
			@PathParam("id") @ApiParam(name="id", description="Role id") String id);
	
	
	/**
	 * Add permissions to role.
	 * @param roleName
	 * @param permissions
	 * @return
	 */
	@ApiMethod(path = "/api/role/addpermissions/{id}", verb = ApiVerb.POST, description = "Find a role by id.", 
			produces = { MediaType.APPLICATION_JSON }, consumes = { MediaType.APPLICATION_JSON })
	@ApiHeaders(headers = {
			@ApiHeader(name = "signature", description = "Authentication signature."),
			@ApiHeader(name = "public-key", description = "Public key of the application.") })
	
	@Path("/addpermissions/{id}")
	@POST
	@Produces(MediaType.APPLICATION_JSON)
	public abstract @ApiResponseObject Response addPermissions(
			@PathParam("roleName") @ApiParam(name="roleName", description="Role name") String roleName,@ApiBodyObject  List<String> permissions);
	
	public abstract Role findByNameInternal(String role);
	
	//public Response findAll();
	
	//public Response count();
	
	//public Response deactivate(String roleName);
}
